/***************************************************************************//**
 * @file dac_buffer.c
 * @brief Implementation of DAC LUT driver.
 * @author Istvan Csomortani (istvan.csomortani@analog.com)
 ********************************************************************************
 * Copyright 2014-2016(c) Analog Devices, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. Neither the name of Analog Devices, Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/
#include "dac_buffer.h"

/******************************************************************************/
/******************************* Constant definitions *************************/
/******************************************************************************/

/* Sine Look Up Table */
static const uint16_t sine_lut[1024] = {
		0x0000,0x1591,0x2A5C,0x3D9F,0x4EA9,0x5CDD,0x67B7,0x6ED4,0x71F1,
		0x70F2,0x6BDF,0x62E9,0x5661,0x46BC,0x3489,0x2071,0x0B2E,0xF584,
		0xE03A,0xCC16,0xB9D1,0xAA14,0x9D71,0x945B,0x8F28,0x8E07,0x9102,
		0x97FF,0xA2BB,0xB0D5,0xC1CB,0xD4FE,0xE9BF,0xFF4D,0x14E1,0x29B5,
		0x3D08,0x4E27,0x5C75,0x676C,0x6EA9,0x71E7,0x710A,0x6C19,0x6342,
		0x56D6,0x4748,0x3528,0x211D,0x0BE0,0xF637,0xE0E7,0xCCB6,0xBA5F,
		0xAA8A,0x9DCB,0x9497,0x8F43,0x8E00,0x90D9,0x97B5,0xA255,0xB055,
		0xC135,0xD458,0xE90F,0xFE9A,0x1431,0x290E,0x3C70,0x4DA4,0x5C0B,
		0x6720,0x6E7D,0x71DD,0x7122,0x6C52,0x639A,0x574A,0x47D4,0x35C6,
		0x21C8,0x0C92,0xF6E9,0xE193,0xCD56,0xBAED,0xAB01,0x9E27,0x94D4,
		0x8F5F,0x8DFA,0x90B2,0x976D,0xA1EF,0xAFD5,0xC09F,0xD3B3,0xE860,
		0xFDE7,0x1380,0x2867,0x3BD8,0x4D20,0x5BA1,0x66D3,0x6E50,0x71D2,
		0x7138,0x6C8A,0x63F1,0x57BD,0x485F,0x3664,0x2273,0x0D45,0xF79C,
		0xE240,0xCDF7,0xBB7C,0xAB79,0x9E84,0x9512,0x8F7C,0x8DF5,0x908B,
		0x9726,0xA18A,0xAF56,0xC00B,0xD30E,0xE7B1,0xFD34,0x12D0,0x27BF,
		0x3B3F,0x4C9C,0x5B36,0x6685,0x6E21,0x71C5,0x714E,0x6CC0,0x6447,
		0x582F,0x48E9,0x3701,0x231E,0x0DF6,0xF84F,0xE2ED,0xCE98,0xBC0B,
		0xABF2,0x9EE1,0x9551,0x8F9A,0x8DF1,0x9065,0x96E0,0xA126,0xAED7,
		0xBF77,0xD26A,0xE702,0xFC81,0x121F,0x2717,0x3AA6,0x4C17,0x5ACA,
		0x6636,0x6DF2,0x71B7,0x7162,0x6CF6,0x649C,0x58A0,0x4972,0x379E,
		0x23C8,0x0EA8,0xF902,0xE39B,0xCF3A,0xBC9C,0xAC6C,0x9F40,0x9591,
		0x8FB9,0x8DEE,0x9041,0x969B,0xA0C3,0xAE5A,0xBEE3,0xD1C6,0xE653,
		0xFBCE,0x116E,0x266E,0x3A0C,0x4B91,0x5A5D,0x65E6,0x6DC2,0x71A8,
		0x7175,0x6D2A,0x64F0,0x5911,0x49FB,0x383A,0x2472,0x0F5A,0xF9B5,
		0xE448,0xCFDC,0xBD2D,0xACE6,0x9F9F,0x95D2,0x8FD9,0x8DED,0x901D,
		0x9657,0xA061,0xADDD,0xBE50,0xD122,0xE5A5,0xFB1B,0x10BD,0x25C5,
		0x3971,0x4B0A,0x59EF,0x6595,0x6D90,0x7198,0x7187,0x6D5E,0x6543,
		0x5980,0x4A83,0x38D6,0x251C,0x100B,0xFA68,0xE4F6,0xD07F,0xBDBE,
		0xAD61,0x9FFF,0x9614,0x8FFB,0x8DEC,0x8FFB,0x9614,0x9FFF,0xAD61,
		0xBDBE,0xD07F,0xE4F6,0xFA68,0x100B,0x251C,0x38D6,0x4A83,0x5980,
		0x6543,0x6D5E,0x7187,0x7198,0x6D90,0x6595,0x59EF,0x4B0A,0x3971,
		0x25C5,0x10BD,0xFB1B,0xE5A5,0xD122,0xBE50,0xADDD,0xA061,0x9657,
		0x901D,0x8DED,0x8FD9,0x95D2,0x9F9F,0xACE6,0xBD2D,0xCFDC,0xE448,
		0xF9B5,0x0F5A,0x2472,0x383A,0x49FB,0x5911,0x64F0,0x6D2A,0x7175,
		0x71A8,0x6DC2,0x65E6,0x5A5D,0x4B91,0x3A0C,0x266E,0x116E,0xFBCE,
		0xE653,0xD1C6,0xBEE3,0xAE5A,0xA0C3,0x969B,0x9041,0x8DEE,0x8FB9,
		0x9591,0x9F40,0xAC6C,0xBC9C,0xCF3A,0xE39B,0xF902,0x0EA8,0x23C8,
		0x379E,0x4972,0x58A0,0x649C,0x6CF6,0x7162,0x71B7,0x6DF2,0x6636,
		0x5ACA,0x4C17,0x3AA6,0x2717,0x121F,0xFC81,0xE702,0xD26A,0xBF77,
		0xAED7,0xA126,0x96E0,0x9065,0x8DF1,0x8F9A,0x9551,0x9EE1,0xABF2,
		0xBC0B,0xCE98,0xE2ED,0xF84F,0x0DF6,0x231E,0x3701,0x48E9,0x582F,
		0x6447,0x6CC0,0x714E,0x71C5,0x6E21,0x6685,0x5B36,0x4C9C,0x3B3F,
		0x27BF,0x12D0,0xFD34,0xE7B1,0xD30E,0xC00B,0xAF56,0xA18A,0x9726,
		0x908B,0x8DF5,0x8F7C,0x9512,0x9E84,0xAB79,0xBB7C,0xCDF7,0xE240,
		0xF79C,0x0D45,0x2273,0x3664,0x485F,0x57BD,0x63F1,0x6C8A,0x7138,
		0x71D2,0x6E50,0x66D3,0x5BA1,0x4D20,0x3BD8,0x2867,0x1380,0xFDE7,
		0xE860,0xD3B3,0xC09F,0xAFD5,0xA1EF,0x976D,0x90B2,0x8DFA,0x8F5F,
		0x94D4,0x9E27,0xAB01,0xBAED,0xCD56,0xE193,0xF6E9,0x0C92,0x21C8,
		0x35C6,0x47D4,0x574A,0x639A,0x6C52,0x7122,0x71DD,0x6E7D,0x6720,
		0x5C0B,0x4DA4,0x3C70,0x290E,0x1431,0xFE9A,0xE90F,0xD458,0xC135,
		0xB055,0xA255,0x97B5,0x90D9,0x8E00,0x8F43,0x9497,0x9DCB,0xAA8A,
		0xBA5F,0xCCB6,0xE0E7,0xF637,0x0BE0,0x211D,0x3528,0x4748,0x56D6,
		0x6342,0x6C19,0x710A,0x71E7,0x6EA9,0x676C,0x5C75,0x4E27,0x3D08,
		0x29B5,0x14E1,0xFF4D,0xE9BF,0xD4FE,0xC1CB,0xB0D5,0xA2BB,0x97FF,
		0x9102,0x8E07,0x8F28,0x945B,0x9D71,0xAA14,0xB9D1,0xCC16,0xE03A,
		0xF584,0x0B2E,0x2071,0x3489,0x46BC,0x5661,0x62E9,0x6BDF,0x70F2,
		0x71F1,0x6ED4,0x67B7,0x5CDD,0x4EA9,0x3D9F,0x2A5C,0x1591,0x0000,
		0xEA6F,0xD5A4,0xC261,0xB157,0xA323,0x9849,0x912C,0x8E0F,0x8F0E,
		0x9421,0x9D17,0xA99F,0xB944,0xCB77,0xDF8F,0xF4D2,0x0A7C,0x1FC6,
		0x33EA,0x462F,0x55EC,0x628F,0x6BA5,0x70D8,0x71F9,0x6EFE,0x6801,
		0x5D45,0x4F2B,0x3E35,0x2B02,0x1641,0x00B3,0xEB1F,0xD64B,0xC2F8,
		0xB1D9,0xA38B,0x9894,0x9157,0x8E19,0x8EF6,0x93E7,0x9CBE,0xA92A,
		0xB8B8,0xCAD8,0xDEE3,0xF420,0x09C9,0x1F19,0x334A,0x45A1,0x5576,
		0x6235,0x6B69,0x70BD,0x7200,0x6F27,0x684B,0x5DAB,0x4FAB,0x3ECB,
		0x2BA8,0x16F1,0x0166,0xEBCF,0xD6F2,0xC390,0xB25C,0xA3F5,0x98E0,
		0x9183,0x8E23,0x8EDE,0x93AE,0x9C66,0xA8B6,0xB82C,0xCA3A,0xDE38,
		0xF36E,0x0917,0x1E6D,0x32AA,0x4513,0x54FF,0x61D9,0x6B2C,0x70A1,
		0x7206,0x6F4E,0x6893,0x5E11,0x502B,0x3F61,0x2C4D,0x17A0,0x0219,
		0xEC80,0xD799,0xC428,0xB2E0,0xA45F,0x992D,0x91B0,0x8E2E,0x8EC8,
		0x9376,0x9C0F,0xA843,0xB7A1,0xC99C,0xDD8D,0xF2BB,0x0864,0x1DC0,
		0x3209,0x4484,0x5487,0x617C,0x6AEE,0x7084,0x720B,0x6F75,0x68DA,
		0x5E76,0x50AA,0x3FF5,0x2CF2,0x184F,0x02CC,0xED30,0xD841,0xC4C1,
		0xB364,0xA4CA,0x997B,0x91DF,0x8E3B,0x8EB2,0x9340,0x9BB9,0xA7D1,
		0xB717,0xC8FF,0xDCE2,0xF20A,0x07B1,0x1D13,0x3168,0x43F5,0x540E,
		0x611F,0x6AAF,0x7066,0x720F,0x6F9B,0x6920,0x5EDA,0x5129,0x4089,
		0x2D96,0x18FE,0x037F,0xEDE1,0xD8E9,0xC55A,0xB3E9,0xA536,0x99CA,
		0x920E,0x8E49,0x8E9E,0x930A,0x9B64,0xA760,0xB68E,0xC862,0xDC38,
		0xF158,0x06FE,0x1C65,0x30C6,0x4364,0x5394,0x60C0,0x6A6F,0x7047,
		0x7212,0x6FBF,0x6965,0x5F3D,0x51A6,0x411D,0x2E3A,0x19AD,0x0432,
		0xEE92,0xD992,0xC5F4,0xB46F,0xA5A3,0x9A1A,0x923E,0x8E58,0x8E8B,
		0x92D6,0x9B10,0xA6EF,0xB605,0xC7C6,0xDB8E,0xF0A6,0x064B,0x1BB8,
		0x3024,0x42D3,0x531A,0x6061,0x6A2E,0x7027,0x7213,0x6FE3,0x69A9,
		0x5F9F,0x5223,0x41B0,0x2EDE,0x1A5B,0x04E5,0xEF43,0xDA3B,0xC68F,
		0xB4F6,0xA611,0x9A6B,0x9270,0x8E68,0x8E79,0x92A2,0x9ABD,0xA680,
		0xB57D,0xC72A,0xDAE4,0xEFF5,0x0598,0x1B0A,0x2F81,0x4242,0x529F,
		0x6001,0x69EC,0x7005,0x7214,0x7005,0x69EC,0x6001,0x529F,0x4242,
		0x2F81,0x1B0A,0x0598,0xEFF5,0xDAE4,0xC72A,0xB57D,0xA680,0x9ABD,
		0x92A2,0x8E79,0x8E68,0x9270,0x9A6B,0xA611,0xB4F6,0xC68F,0xDA3B,
		0xEF43,0x04E5,0x1A5B,0x2EDE,0x41B0,0x5223,0x5F9F,0x69A9,0x6FE3,
		0x7213,0x7027,0x6A2E,0x6061,0x531A,0x42D3,0x3024,0x1BB8,0x064B,
		0xF0A6,0xDB8E,0xC7C6,0xB605,0xA6EF,0x9B10,0x92D6,0x8E8B,0x8E58,
		0x923E,0x9A1A,0xA5A3,0xB46F,0xC5F4,0xD992,0xEE92,0x0432,0x19AD,
		0x2E3A,0x411D,0x51A6,0x5F3D,0x6965,0x6FBF,0x7212,0x7047,0x6A6F,
		0x60C0,0x5394,0x4364,0x30C6,0x1C65,0x06FE,0xF158,0xDC38,0xC862,
		0xB68E,0xA760,0x9B64,0x930A,0x8E9E,0x8E49,0x920E,0x99CA,0xA536,
		0xB3E9,0xC55A,0xD8E9,0xEDE1,0x037F,0x18FE,0x2D96,0x4089,0x5129,
		0x5EDA,0x6920,0x6F9B,0x720F,0x7066,0x6AAF,0x611F,0x540E,0x43F5,
		0x3168,0x1D13,0x07B1,0xF20A,0xDCE2,0xC8FF,0xB717,0xA7D1,0x9BB9,
		0x9340,0x8EB2,0x8E3B,0x91DF,0x997B,0xA4CA,0xB364,0xC4C1,0xD841,
		0xED30,0x02CC,0x184F,0x2CF2,0x3FF5,0x50AA,0x5E76,0x68DA,0x6F75,
		0x720B,0x7084,0x6AEE,0x617C,0x5487,0x4484,0x3209,0x1DC0,0x0864,
		0xF2BB,0xDD8D,0xC99C,0xB7A1,0xA843,0x9C0F,0x9376,0x8EC8,0x8E2E,
		0x91B0,0x992D,0xA45F,0xB2E0,0xC428,0xD799,0xEC80,0x0219,0x17A0,
		0x2C4D,0x3F61,0x502B,0x5E11,0x6893,0x6F4E,0x7206,0x70A1,0x6B2C,
		0x61D9,0x54FF,0x4513,0x32AA,0x1E6D,0x0917,0xF36E,0xDE38,0xCA3A,
		0xB82C,0xA8B6,0x9C66,0x93AE,0x8EDE,0x8E23,0x9183,0x98E0,0xA3F5,
		0xB25C,0xC390,0xD6F2,0xEBCF,0x0166,0x16F1,0x2BA8,0x3ECB,0x4FAB,
		0x5DAB,0x684B,0x6F27,0x7200,0x70BD,0x6B69,0x6235,0x5576,0x45A1,
		0x334A,0x1F19,0x09C9,0xF420,0xDEE3,0xCAD8,0xB8B8,0xA92A,0x9CBE,
		0x93E7,0x8EF6,0x8E19,0x9157,0x9894,0xA38B,0xB1D9,0xC2F8,0xD64B,
		0xEB1F,0x00B3,0x1641,0x2B02,0x3E35,0x4F2B,0x5D45,0x6801,0x6EFE,
		0x71F9,0x70D8,0x6BA5,0x628F,0x55EC,0x462F,0x33EA,0x1FC6,0x0A7C,
		0xF4D2,0xDF8F,0xCB77,0xB944,0xA99F,0x9D17,0x9421,0x8F0E,0x8E0F,
		0x912C,0x9849,0xA323,0xB157,0xC261,0xD5A4,0xEA6F};

/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/

uint32_t dac_buffer_load(dac_core core, uint32_t start_address) {

	uint32_t no_of_samples;
	uint32_t index_i, index_q;
	uint32_t index_mem = 0;

	no_of_samples = sizeof(sine_lut) / sizeof(typeof(sine_lut[0]));

	for (index_i = 0; index_i < no_of_samples; index_i++) {
		 /* Phase shifted by 90 degree */
		index_q = (index_i + 256) % no_of_samples;

		switch (core.no_of_channels) {
			case 1:
				ad_reg_write_16(start_address + index_mem * 2, sine_lut[index_i]);
				index_mem += 1;
				break;
			case 2:
				ad_reg_write_16(start_address + (index_mem + 0) * 2, sine_lut[index_i]);
				ad_reg_write_16(start_address + (index_mem + 1) * 2, sine_lut[index_q]);
				index_mem += 2;
				break;
			case 4:
				ad_reg_write_16(start_address + (index_mem + 0) * 2, sine_lut[index_i]);
				ad_reg_write_16(start_address + (index_mem + 1) * 2, sine_lut[index_q]);
				ad_reg_write_16(start_address + (index_mem + 2) * 2, sine_lut[index_i]);
				ad_reg_write_16(start_address + (index_mem + 3) * 2, sine_lut[index_q]);
				index_mem += 4;
				break;
			default:
				ad_printf("Unsupported mode.\n\r");
				return -1;
		}
	}

	ad_dcache_flush();

	return (core.no_of_channels * no_of_samples);
}

